using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using FrameworkX.ObjectSpace.Validation;

namespace FrameworkX.ObjectSpace.Validation
{
    public static class ValidationHelper
    {
        public static bool ValidateUIAndObject(Control control, ErrorProvider errorProvider, object obj)
        {
            bool valid = true;
            if (control is Form )
            {
                errorProvider.Clear();
            }
            foreach (Control ctl in control.Controls)
            {
                if (IsContainerControl(ctl))
                {
                    if (!ValidateUIAndObject(ctl, errorProvider, obj))
                        valid = false;
                }
                else
                {
                    if (!ValidateUIAndObject(ctl, ((Control)ctl).Text, errorProvider, obj))
                        valid = false;
                }
            }

            return valid;
        }

        private static bool IsContainerControl (Control ctl)
        {
            if (ctl is ContainerControl)
                return true;
            if (ctl is GroupBox)
                return true;

            return false;
        }

        private static bool ValidateUIAndObject(Control control, string controlText, ErrorProvider errorProvider, object obj)
        {
            bool valid = true;
            if (control.Tag != null)
            {
                // Get the property path 
                string fullPropertyPath = control.Tag.ToString();
                // Get the property name by replacing the control name
                string propertyName = fullPropertyPath.Replace(obj.GetType().Name + ".", "");
                // Get the property object
                PropertyInfo pinfo = obj.GetType().GetProperty(propertyName);
                
                object[] attributes = pinfo.GetCustomAttributes (typeof(ValidationAttribute), true);

                if (attributes.Length>0)
                {
                    StringBuilder sbErrorString = new StringBuilder();
                    foreach (object attr in attributes)
                    {
                        ValidationAttribute validationAttribute = (ValidationAttribute)attr;
                        ValidationResult result = validationAttribute.Validate
                            (pinfo.Name, controlText);
                        if (!result.IsSuccessful)
                        {
                            if (sbErrorString.Length > 0)
                            {
                                sbErrorString.Append("\n" + result.Message);
                            }
                            else
                            {
                                sbErrorString.Append(result.Message);
                            }
                        }
                    }                    
                    if (sbErrorString.Length >0 )
                    {
                        errorProvider.SetError(control, sbErrorString.ToString());
                        valid =false;
                    }
                }
            }
            return valid ;
        }

        private static string GetErrorMessage(ValidationAttribute attribute, string valueText, PropertyInfo property, object obj)
        {
            if (attribute is NotEmptyAttribute)
            {
                if (valueText.Equals(string.Empty))
                {
                    return string.Format("{0} cannot be blank.",
                        Util.GetSpacedStringFromWordCapitalizedString(property.Name));
                }
                else
                {
                    return string.Empty;
                }
            }
            return string.Empty;
        }


    }
}
